/* Copyright 2018 Canaan Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS},
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include "gc0328.h"
#include "dvp.h"
#include "plic.h"
#include "sleep.h"
#include "sensor.h"
#include "mphalport.h"
#include "cambus.h"
#if 1
enum
{
    GC0328_RGB_Gamma_m0 = 0,
    GC0328_RGB_Gamma_m1,
    GC0328_RGB_Gamma_m2,
    GC0328_RGB_Gamma_m3,
    GC0328_RGB_Gamma_m4,
    GC0328_RGB_Gamma_m5,
    GC0328_RGB_Gamma_m6,
    GC0328_RGB_Gamma_night
};

#define GC0328_RGB_Gamma GC0328_RGB_Gamma_night

/** The default register settings**/
uint8_t sensor_default_regs[][2] = {
    {0xfe, 0x80},//reset
    {0xfe, 0x80},//reset
    {0xfc, 0x16},//set digital clock
    {0xfc, 0x16},//set digital clock
    {0xfc, 0x16},//set digital clock
    {0xfc, 0x16},//set digital clock

    {0xfe, 0x00},//select page0
    {0x4f, 0x00},//AEC disable
    {0x42, 0x00},//ABW disable
    {0x03, 0x00},//clear Exposure time MSB[11:8]
    {0x04, 0xc0},//clear Exposure time LSB[7:0]
    {0x77, 0x62},//set AWB red gain
    {0x78, 0x40},//set AWB green gain 
    {0x79, 0x4d},//set AWB blue gain

    {0xfe, 0x01},//select p1
    {0x4f, 0x00},//unknow
    {0x4c, 0x01},//unknow
    {0xfe, 0x00},//select p0
//////////////////////////////
///////////AWB///////////
////////////////////////////////
#if 1
    {0xfe, 0x01},//select p1
    {0x51, 0x80}, //20 Dominate luma THD LSB[7:0]
    {0x52, 0x12}, //16 1f Dominate luma THD MSB[15:8]
    {0x53, 0x80}, //40 mix luma number THD LSB[7:0]
    {0x54, 0x60}, //9f mix luma number THD MSB[15:8]
    {0x55, 0x04}, //01 pre AWB debug pixel select
    {0x56, 0x0e}, //00 AWB tone mode
    {0x5b, 0x02}, //02 mix base gain and adaptive gain limit
    {0x61, 0xdc}, //R2G_stand0[70] unknow
    {0x62, 0xca}, //B2G_stand0[70] unknow

    {0x70, 0xf5}, //AWB high range
    {0x71, 0x0a}, //
    {0x72, 0x18}, // y2c
    {0x73, 0x30}, //28 20  AWB_C_inter
    {0x74, 0x58}, //40 20   AWB_C_max
    {0x7c, 0x71}, //AWB speed,AWB margin
    {0x7d, 0x00}, //10 AWB every N
    {0x76, 0x8f}, //move mode en,Move mode TH
    {0x79, 0x00}, //00 AWB config
    {0x4f, 0x00}, //unknow 
    {0x4d, 0x34}, //  |
    {0x4e, 0x04}, //  |
    {0x4e, 0x02}, //  |
    {0x4e, 0x02}, //  |
    {0x4d, 0x43}, //  |
    {0x4e, 0x04}, //  |
    {0x4e, 0x04}, //  |  D50 
    {0x4e, 0x02}, //  |d65 add 
    {0x4e, 0x02}, //  |d65 add
    {0x4d, 0x53}, //  |
    {0x4e, 0x08}, //  | cwf  
    {0x4e, 0x04}, //  |
    {0x4e, 0x02}, //  | D65  
    {0x4e, 0x02}, //  | D65  
    {0x4d, 0x63}, //  |
    {0x4e, 0x10}, //  |tl84
    {0x4d, 0x72}, //  |
    {0x4e, 0x20}, //  |
    {0x4e, 0x20}, //  |
    {0x4d, 0x82}, //  |
    {0x4e, 0x20}, //  | A
    {0x4e, 0x20}, //  |
    {0x4d, 0x92}, //  |
    {0x4e, 0x20}, //  | A
    {0x4e, 0x20}, //  |
    {0x4d, 0xa0}, //  |
    {0x4e, 0x40}, //  |   H
    {0x4e, 0x40}, //  |
    {0x4e, 0x40}, //  ↓
    {0x4f, 0x01}, //  unknow
    {0x50, 0x84}, //AWB PRE_enable
    {0xfe, 0x00}, //page0

#else //  mtk  awb
    {0xfe, 0x01},
    {0x51, 0x80},
    {0x52, 0x12},
    {0x53, 0x80},
    {0x54, 0x60},
    {0x55, 0x01},
    {0x56, 0x06},
    {0x5b, 0x02},
    {0x61, 0xdc},
    {0x62, 0xdc},
    {0x7c, 0x71},
    {0x7d, 0x00},
    {0x76, 0x00},
    {0x79, 0x20},
    {0x7b, 0x00},
    {0x70, 0xFF},
    {0x71, 0x00},
    {0x72, 0x10},
    {0x73, 0x40},
    {0x74, 0x40},
    ////AWB//
    {0x50, 0x00},
    {0xfe, 0x01},
    {0x4f, 0x00},
    {0x4c, 0x01},
    {0x4f, 0x00},
    {0x4f, 0x00},
    {0x4f, 0x00},
    {0x4d, 0x36},
    {0x4e, 0x02},
    {0x4d, 0x46},
    {0x4e, 0x02},
    {0x4e, 0x02},
    {0x4d, 0x53},
    {0x4e, 0x08},
    {0x4e, 0x04},
    {0x4e, 0x04},
    {0x4d, 0x63},
    {0x4e, 0x08},
    {0x4e, 0x08},
    {0x4d, 0x82},
    {0x4e, 0x20},
    {0x4e, 0x20},
    {0x4d, 0x92},
    {0x4e, 0x40},
    {0x4d, 0xa2},
    {0x4e, 0x40},
    {0x4f, 0x01},

    {0x50, 0x88},
    {0xfe, 0x00},
#endif

    ////////////////////////////////////////////////
    ////////////     BLK      //////////////////////
    ////////////////////////////////////////////////
    {0x27, 0x00}, 
    {0x2a, 0x40},
    {0x2b, 0x40},
    {0x2c, 0x40},
    {0x2d, 0x40},

    //////////////////////////////////////////////
    ////////// page  0    ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x00},
    
    // {0x0d, 0x01},//Window height MSB | Windowing mode
    // {0x0e, 0xe8},//Window height LSB | Windowing mode
    // {0x0f, 0x02},//Window width MSB | Windowing mode
    // {0x10, 0x88},//Window width LSB | Windowing mode
    // {0x09, 0x00},//Row start MSB | Windowing mode
    // {0x0a, 0x00},//Row start LSB | Windowing mode
    // {0x0b, 0x00},//column start MSB | Windowing mode
    // {0x0c, 0x00},//column start LSB | Windowing mode
    {0x16, 0x00},//Analog gain
    {0x17, 0x16}, //vflip & mirror set 17
    {0x18, 0x0e},//unknow
    {0x19, 0x06},//unknow

    {0x1b, 0x48},//unknow
    {0x1f, 0xC8},//unknow
    {0x20, 0x01},//unknow
    {0x21, 0x78},//unknow
    {0x22, 0xb0},//unknow
    {0x23, 0x06},//unknow
    {0x24, 0x3f},//output pin abilityof driver config
    {0x26, 0x00},//unknow

    {0x50, 0x01},//crop mode | It should be disable

    //global gain for range
    {0x70, 0x85},

    ////////////////////////////////////////////////
    ////////////     block enable      /////////////
    ////////////////////////////////////////////////
    {0x40, 0x7f},//ISP config
    {0x41, 0x24},
    {0x42, 0xff},//enable AWB
    {0x45, 0x00},
    {0x44, 0x26}, // rgb565 format
    {0x46, 0x03}, // hs and vs config

    {0x4b, 0x01}, //
    {0x50, 0x01}, //crop mode

    //DN & EEINTP
    {0x7e, 0x0a},
    {0x7f, 0x03},
    {0x81, 0x15},
    {0x82, 0x85},
    {0x83, 0x02},
    {0x84, 0xe5},
    {0x90, 0xac},
    {0x92, 0x02},
    {0x94, 0x02},
    {0x95, 0x32},

    ///////YCP
    {0xd1, 0x28},
    {0xd2, 0x28},
    {0xdd, 0x58},
    {0xde, 0x36},
    {0xe4, 0x88},
    {0xe5, 0x40},
    {0xd7, 0x0e},

/////////////////////////////
//////////////// GAMMA //////
/////////////////////////////

#if (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m0)
    {0xfe, 0x00},
    {0xBF, 0x0E},
    {0xc0, 0x1C},
    {0xc1, 0x34},
    {0xc2, 0x48},
    {0xc3, 0x5A},
    {0xc4, 0x6B},
    {0xc5, 0x7B},
    {0xc6, 0x95},
    {0xc7, 0xAB},
    {0xc8, 0xBF},
    {0xc9, 0xCE},
    {0xcA, 0xD9},
    {0xcB, 0xE4},
    {0xcC, 0xEC},
    {0xcD, 0xF7},
    {0xcE, 0xFD},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m1)
    //smallest gamma curve
    {0xfe, 0x00},
    {0xbf, 0x06},
    {0xc0, 0x12},
    {0xc1, 0x22},
    {0xc2, 0x35},
    {0xc3, 0x4b},
    {0xc4, 0x5f},
    {0xc5, 0x72},
    {0xc6, 0x8d},
    {0xc7, 0xa4},
    {0xc8, 0xb8},
    {0xc9, 0xc8},
    {0xca, 0xd4},
    {0xcb, 0xde},
    {0xcc, 0xe6},
    {0xcd, 0xf1},
    {0xce, 0xf8},
    {0xcf, 0xfd},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m2)
    {0xBF, 0x08},
    {0xc0, 0x0F},
    {0xc1, 0x21},
    {0xc2, 0x32},
    {0xc3, 0x43},
    {0xc4, 0x50},
    {0xc5, 0x5E},
    {0xc6, 0x78},
    {0xc7, 0x90},
    {0xc8, 0xA6},
    {0xc9, 0xB9},
    {0xcA, 0xC9},
    {0xcB, 0xD6},
    {0xcC, 0xE0},
    {0xcD, 0xEE},
    {0xcE, 0xF8},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m3)
    {0xBF, 0x0B},
    {0xc0, 0x16},
    {0xc1, 0x29},
    {0xc2, 0x3C},
    {0xc3, 0x4F},
    {0xc4, 0x5F},
    {0xc5, 0x6F},
    {0xc6, 0x8A},
    {0xc7, 0x9F},
    {0xc8, 0xB4},
    {0xc9, 0xC6},
    {0xcA, 0xD3},
    {0xcB, 0xDD},
    {0xcC, 0xE5},
    {0xcD, 0xF1},
    {0xcE, 0xFA},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m4)
    {0xBF, 0x0E},
    {0xc0, 0x1C},
    {0xc1, 0x34},
    {0xc2, 0x48},
    {0xc3, 0x5A},
    {0xc4, 0x6B},
    {0xc5, 0x7B},
    {0xc6, 0x95},
    {0xc7, 0xAB},
    {0xc8, 0xBF},
    {0xc9, 0xCE},
    {0xcA, 0xD9},
    {0xcB, 0xE4},
    {0xcC, 0xEC},
    {0xcD, 0xF7},
    {0xcE, 0xFD},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m5)
    {0xBF, 0x10},
    {0xc0, 0x20},
    {0xc1, 0x38},
    {0xc2, 0x4E},
    {0xc3, 0x63},
    {0xc4, 0x76},
    {0xc5, 0x87},
    {0xc6, 0xA2},
    {0xc7, 0xB8},
    {0xc8, 0xCA},
    {0xc9, 0xD8},
    {0xcA, 0xE3},
    {0xcB, 0xEB},
    {0xcC, 0xF0},
    {0xcD, 0xF8},
    {0xcE, 0xFD},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_m6)
    // largest gamma curve
    {0xBF, 0x14},
    {0xc0, 0x28},
    {0xc1, 0x44},
    {0xc2, 0x5D},
    {0xc3, 0x72},
    {0xc4, 0x86},
    {0xc5, 0x95},
    {0xc6, 0xB1},
    {0xc7, 0xC6},
    {0xc8, 0xD5},
    {0xc9, 0xE1},
    {0xcA, 0xEA},
    {0xcB, 0xF1},
    {0xcC, 0xF5},
    {0xcD, 0xFB},
    {0xcE, 0xFE},
    {0xcF, 0xFF},
#elif (GC0328_RGB_Gamma == GC0328_RGB_Gamma_night)
    //Gamma for night mode
    {0xBF, 0x0B},
    {0xc0, 0x16},
    {0xc1, 0x29},
    {0xc2, 0x3C},
    {0xc3, 0x4F},
    {0xc4, 0x5F},
    {0xc5, 0x6F},
    {0xc6, 0x8A},
    {0xc7, 0x9F},
    {0xc8, 0xB4},
    {0xc9, 0xC6},
    {0xcA, 0xD3},
    {0xcB, 0xDD},
    {0xcC, 0xE5},
    {0xcD, 0xF1},
    {0xcE, 0xFA},
    {0xcF, 0xFF},
#endif

    ///Y gamma
    {0xfe, 0x00},
    {0x63, 0x00},
    {0x64, 0x05},
    {0x65, 0x0b},
    {0x66, 0x19},
    {0x67, 0x2e},
    {0x68, 0x40},
    {0x69, 0x54},
    {0x6a, 0x66},
    {0x6b, 0x86},
    {0x6c, 0xa7},
    {0x6d, 0xc6},
    {0x6e, 0xe4},
    {0x6f, 0xFF},

    //////ASDE
    {0xfe, 0x01},
    {0x18, 0x02},
    {0xfe, 0x00},
    {0x98, 0x00},
    {0x9b, 0x20},
    {0x9c, 0x80},
    {0xa4, 0x10},
    {0xa8, 0xB0},
    {0xaa, 0x40},
    {0xa2, 0x23},
    {0xad, 0x01},

    //////////////////////////////////////////////
    ////////// AEC    ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x01},
    {0x9c, 0x02},//ABS config
    {0x08, 0xa0},//windown width | Measure Window
    {0x09, 0xe8},//windown height | Measure Window

    {0x10, 0x00},//AEC_mode1
    {0x11, 0x11},//AEC_mode2
    {0x12, 0x10},//AEC_mode3
    {0x13, 0x98},//AEC_target_Y_start
    {0x15, 0xfc},//AEC_high_range
    {0x18, 0x03},//AEC_luma_div
    {0x21, 0xc0},//AEC_max_post_dg_gain
    {0x22, 0x60},//AEC_max_pre_dg_gain
    {0x23, 0x30},//AEC_max_dg_gain
    {0x25, 0x00},//unknow
    {0x24, 0x14},//unknow

    {0xfe, 0x00},
    {0x05, 0x00},//HB MSB | HBlank 02
    {0x06, 0xef},//HB LSB | HBlank 2c
    {0x07, 0x00},//VB MSB | VBLANK
    {0x08, 0x18},//VB LSB | VBLANK b8

    {0xfe, 0x01},
    {0x29, 0x00}, //anti-flicker step [118]
    {0x2a, 0x60}, //anti-flicker step [70]

    {0x2b, 0x02}, //exp level 0  14.28fps
    {0x2c, 0xa0},
    {0x2d, 0x03}, //exp level 1  12.50fps
    {0x2e, 0x00},
    {0x2f, 0x05}, //exp level 2  10.00fps
    {0x30, 0x40},
    {0x31, 0x07}, //exp level 3  7.14fps
    {0x32, 0x80},
    {0x33, 0x00}, //set exp level | 02

    //////////////////////////////////////
    ////////////LSC//////////////////////
    //////////////////////////////////////
    //gc0328 Alight lsc reg setting list
    ////Record date: 2013-04-01 15:59:05
    {0xfe, 0x01},
    {0xc0, 0x0d},
    {0xc1, 0x05},
    {0xc2, 0x00},
    {0xc6, 0x07},
    {0xc7, 0x03},
    {0xc8, 0x01},
    {0xba, 0x19},
    {0xbb, 0x10},
    {0xbc, 0x0a},
    {0xb4, 0x19},
    {0xb5, 0x0d},
    {0xb6, 0x09},
    {0xc3, 0x00},
    {0xc4, 0x00},
    {0xc5, 0x0e},
    {0xc9, 0x00},
    {0xca, 0x00},
    {0xcb, 0x00},
    {0xbd, 0x07},
    {0xbe, 0x00},
    {0xbf, 0x0e},
    {0xb7, 0x09},
    {0xb8, 0x00},
    {0xb9, 0x0d},
    {0xa8, 0x01},
    {0xa9, 0x00},
    {0xaa, 0x03},
    {0xab, 0x02},
    {0xac, 0x05},
    {0xad, 0x0c},
    {0xae, 0x03},
    {0xaf, 0x00},
    {0xb0, 0x04},
    {0xb1, 0x04},
    {0xb2, 0x03},
    {0xb3, 0x08},
    {0xa4, 0x00},
    {0xa5, 0x00},
    {0xa6, 0x00},
    {0xa7, 0x00},
    {0xa1, 0x3c},
    {0xa2, 0x50},
    {0xfe, 0x00},

    ///cct
    {0xB1, 0x00},
    {0xB2, 0x02},
    {0xB3, 0x07},
    {0xB4, 0xf0},
    {0xB5, 0x05},
    {0xB6, 0xf8},

    {0xfe, 0x00},
    {0x27, 0xf7},//Blk_mode
    {0x28, 0x7F},//Blk_mode
    {0x29, 0x20},//Blk
    {0x33, 0x20},//Blk
    {0x34, 0x20},//Blk
    {0x35, 0x20},//Blk
    {0x36, 0x20},//Blk
    {0x32, 0x08},//Blk

    {0x47, 0x00},//Global_offset_dark MSB
    {0x48, 0x00},//Global_offset_dark LSB

    {0xfe, 0x01},//
    {0x79, 0x00},//AWB
    {0x7d, 0x00},//AWB
    {0x50, 0x88},//AWB
    {0x5b, 0x04},//AWB
    {0x76, 0x8f},//AWB
    {0x80, 0x70},//AWB gain limit for R
    {0x81, 0x70},//AWB gain limit for G
    {0x82, 0xb0},//AWB gain limit for B
    {0x70, 0xff},//AWB high range
    {0x71, 0x00},//AWB low range
    {0x72, 0x10},//
    {0x73, 0x40},
    {0x74, 0x40},

    {0xfe, 0x00},
    {0x70, 0xa0},//Global_gain 45
    {0x4f, 0x01},//AEC enable 
    {0xf1, 0x07},//output enable

    {0xf2, 0x01},//data output enable

#if 0 //hqvga
    {0xfe, 0x00},
	{0x4b, 0x8a},
	{0x50, 0x01},
	{0x51, 0x00},
	{0x52, 0x00},
	{0x53, 0x00},
	{0x54, 0x00},
	{0x55, 0x00},
	{0x56, 0xa0},
	{0x57, 0x00},
	{0x58, 0xf0},
	{0x59, 0x22},
	{0x5a, 0x03},
	{0x5b, 0x00},
	{0x5c, 0x00},
	{0x5d, 0x00},
	{0x5e, 0x00},
	{0x5f, 0x00},
	{0x60, 0x00},
	{0x61, 0x00},
	{0x62, 0x00},
#else //qvga
    {0xfe, 0x00},
    {0x4b, 0x8a},
    {0x50, 0x00},//crop win_mode disable
    // {0x51, 0x00},//window y coordinate MSB
    // {0x52, 0x00},//window y coordinate LSB
    // {0x53, 0x00},//window x coordinate MSB
    // {0x54, 0x00},//window x coordinate LSB
    // {0x55, 0x00},//window height MSB
    // {0x56, 0xf0},//window height LSB
    // {0x57, 0x01},//window width MSB
    // {0x58, 0x40},//window width LSB
    {0x5a, 0x00},//subsample mode 03
    {0x59, 0x22},//subsample ratio
    {0x5b, 0x00},//sub rowN1
    {0x5c, 0x00},//sub rowN2
    {0x5d, 0x00},//sub rwoN3
    {0x5e, 0x00},//sub rowN4
    {0x5f, 0x00},//sub colN1
    {0x60, 0x00},//sub colN2
    {0x61, 0x00},//sub colN3
    {0x62, 0x00},//sub colN4
#endif
    {0x00, 0x00},
};

#else
uint8_t sensor_default_regs[][2] = {
    {0xfe, 0x80},
    {0xfe, 0x80},
    {0xfc, 0x16},
    {0xfc, 0x16},
    {0xfc, 0x16},
    {0xfc, 0x16},

    {0xfe, 0x00},
    {0x4f, 0x00},
    {0x42, 0x00},
    {0x03, 0x00},
    {0x04, 0xc0},
    {0x77, 0x62},
    {0x78, 0x40},
    {0x79, 0x4d},

    {0x05, 0x00},
    {0x06, 0x6a}, //hb
    {0x07, 0x00},
    {0x08, 0x0c}, //vb

    {0xfe, 0x01},
    {0x29, 0x00}, //anti-flicker step [11:8]
    {0x2a, 0x96}, //anti-flicker step [7:0]

    {0x2b, 0x01}, //exp level 0  30fps
    {0x2c, 0xc2},
    {0x2d, 0x02}, //exp level 1  25fps
    {0x2e, 0x58},
    {0x2f, 0x02}, //exp level 2  20fps
    {0x30, 0xee},
    {0x31, 0x05}, //exp level 3  10fps
    {0x32, 0xdc},
    {0xfe, 0x00},

    {0xfe, 0x01},
    {0x4f, 0x00},
    {0x4c, 0x01},
    {0xfe, 0x00},
    //////////////////////////////
    ///////////AWB///////////
    ////////////////////////////////
    {0xfe, 0x01},
    {0x51, 0x80},
    {0x52, 0x12},
    {0x53, 0x80},
    {0x54, 0x60},
    {0x55, 0x01},
    {0x56, 0x06},
    {0x5b, 0x02},
    {0x61, 0xdc},
    {0x62, 0xdc},
    {0x7c, 0x71},
    {0x7d, 0x00},
    {0x76, 0x00},
    {0x79, 0x20},
    {0x7b, 0x00},
    {0x70, 0xFF},
    {0x71, 0x00},
    {0x72, 0x10},
    {0x73, 0x40},
    {0x74, 0x40},
    ////AWB//
    {0x50, 0x00},
    {0xfe, 0x01},
    {0x4f, 0x00},
    {0x4c, 0x01},
    {0x4f, 0x00},
    {0x4f, 0x00},
    {0x4f, 0x00}, //wait clr finish
    {0x4d, 0x36}, ////////////40
    {0x4e, 0x02}, //SPL D65
    {0x4e, 0x02}, //SPL D65
    {0x4d, 0x44}, ////////////40
    {0x4e, 0x02},
    {0x4e, 0x02},
    {0x4e, 0x02}, //SPL D65
    {0x4e, 0x02}, //SPL D65
    {0x4d, 0x53}, /////////////50
    {0x4e, 0x08}, //SPL CWF
    {0x4e, 0x08}, //DNP
    {0x4e, 0x02}, //04//pink      //DNP
    {0x4d, 0x63}, /////////////60
    {0x4e, 0x08}, //TL84
    {0x4e, 0x08}, //TL84
    {0x4d, 0x73}, //////////////80
    {0x4e, 0x20}, //SPL   A
    {0x4d, 0x83}, //////////////80
    {0x4e, 0x20}, //SPL   A
    {0x4f, 0x01},

    {0x50, 0x88},
    {0xfe, 0x00}, //page0

    ////////////////////////////////////////////////
    ////////////     BLK      //////////////////////
    ////////////////////////////////////////////////
    {0x27, 0x00},
    {0x2a, 0x40},
    {0x2b, 0x40},
    {0x2c, 0x40},
    {0x2d, 0x40},

    //////////////////////////////////////////////
    ////////// page  0    ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x00},
    {0x0d, 0x01},
    {0x0e, 0xe8},
    {0x0f, 0x02},
    {0x10, 0x88},
    {0x09, 0x00},
    {0x0a, 0x00},
    {0x0b, 0x00},
    {0x0c, 0x00},
    {0x16, 0x00},
    {0x17, 0x14},
    {0x18, 0x0e},
    {0x19, 0x06},

    {0x1b, 0x48},
    {0x1f, 0xC8},
    {0x20, 0x01},
    {0x21, 0x78},
    {0x22, 0xb0},
    {0x23, 0x04}, // 0x06 20140519 lanking GC0328C
    {0x24, 0x11},
    {0x26, 0x00},

    //crop window  320x240
    {0x50, 0x01}, //crop mode
    {0x51, 0x00},
    {0x52, 0x78},
    {0x53, 0x00},
    {0x54, 0xa0},
    {0x55, 0x00},
    {0x56, 0xf0},
    {0x57, 0x01},
    {0x58, 0x40},

    //global gain for range
    {0x70, 0x85},

    ////////////////////////////////////////////////
    ////////////     block enable      /////////////
    ////////////////////////////////////////////////
    {0x40, 0x7f},
    {0x41, 0x26},
    {0x42, 0xff},
    {0x45, 0x00},
    {0x44, 0xa6}, //RGB565
    {0x46, 0x02},

    {0x4b, 0x01},
    {0x50, 0x01},

    /////DN & EEINTP/////
    {0x7e, 0x0a},
    {0x7f, 0x03},
    {0x80, 0x27}, //  20140915
    {0x81, 0x15},
    {0x82, 0x90},
    {0x83, 0x02},
    {0x84, 0x23}, // 0x22 20140915
    {0x90, 0x2c},
    {0x92, 0x02},
    {0x94, 0x02},
    {0x95, 0x35},

    ///////YCP
    {0xd1, 0x32},
    {0xd2, 0x32},
    {0xdd, 0x18},
    {0xde, 0x32},
    {0xe4, 0x88},
    {0xe5, 0x40},
    {0xd7, 0x0e},

    /////////////////////////////
    //////////////// GAMMA //////
    /////////////////////////////
    //rgb gamma
    {0xfe, 0x00},
    {0xbf, 0x10},
    {0xc0, 0x1c},
    {0xc1, 0x33},
    {0xc2, 0x48},
    {0xc3, 0x5a},
    {0xc4, 0x6b},
    {0xc5, 0x7b},
    {0xc6, 0x95},
    {0xc7, 0xab},
    {0xc8, 0xbf},
    {0xc9, 0xcd},
    {0xca, 0xd9},
    {0xcb, 0xe3},
    {0xcc, 0xeb},
    {0xcd, 0xf7},
    {0xce, 0xfd},
    {0xcf, 0xff},

    ///Y gamma
    {0xfe, 0x00},
    {0x63, 0x00},
    {0x64, 0x05},
    {0x65, 0x0c},
    {0x66, 0x1a},
    {0x67, 0x29},
    {0x68, 0x39},
    {0x69, 0x4b},
    {0x6a, 0x5e},
    {0x6b, 0x82},
    {0x6c, 0xa4},
    {0x6d, 0xc5},
    {0x6e, 0xe5},
    {0x6f, 0xFF},

    //////ASDE
    {0xfe, 0x01},
    {0x18, 0x02},
    {0xfe, 0x00},
    {0x98, 0x00},
    {0x9b, 0x20},
    {0x9c, 0x80},
    {0xa4, 0x10},
    {0xa8, 0xB0},
    {0xaa, 0x40},
    {0xa2, 0x23},
    {0xad, 0x01},

    //////////////////////////////////////////////
    ////////// AEC    ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x01},
    {0x9c, 0x02},
    {0x08, 0xa0},
    {0x09, 0xe8},

    {0x10, 0x00},
    {0x11, 0x11},
    {0x12, 0x10},
    {0x13, 0x80}, ///  lanking +2
    {0x15, 0xfc},
    {0x18, 0x03},
    {0x21, 0xc0},
    {0x22, 0x60},
    {0x23, 0x30},
    {0x25, 0x00},
    {0x24, 0x14},

    //////////////////////////////////////
    ////////////LSC//////////////////////
    //////////////////////////////////////
    //gc0328 Alight lsc reg setting list
    ////Record date: 2013-04-01 15:59:05
    {0xfe, 0x01},
    {0xc0, 0x10},
    {0xc1, 0x0c},
    {0xc2, 0x0a},
    {0xc6, 0x0e},
    {0xc7, 0x0b},
    {0xc8, 0x0a},
    {0xba, 0x26},
    {0xbb, 0x1c},
    {0xbc, 0x1d},
    {0xb4, 0x23},
    {0xb5, 0x1c},
    {0xb6, 0x1a},
    {0xc3, 0x00},
    {0xc4, 0x00},
    {0xc5, 0x00},
    {0xc9, 0x00},
    {0xca, 0x00},
    {0xcb, 0x00},
    {0xbd, 0x00},
    {0xbe, 0x00},
    {0xbf, 0x00},
    {0xb7, 0x07},
    {0xb8, 0x05},
    {0xb9, 0x05},
    {0xa8, 0x07},
    {0xa9, 0x06},
    {0xaa, 0x00},
    {0xab, 0x04},
    {0xac, 0x00},
    {0xad, 0x02},
    {0xae, 0x0d},
    {0xaf, 0x05},
    {0xb0, 0x00},
    {0xb1, 0x07},
    {0xb2, 0x03},
    {0xb3, 0x00},
    {0xa4, 0x00},
    {0xa5, 0x00},
    {0xa6, 0x00},
    {0xa7, 0x00},
    {0xa1, 0x3c},
    {0xa2, 0x50},
    {0xfe, 0x00},

    ///cct
    {0xB1, 0x04},
    {0xB2, 0xfd},
    {0xB3, 0xfc},
    {0xB4, 0xf0},
    {0xB5, 0x05},
    {0xB6, 0xf0},

    //sleep

    {0xfe, 0x00},
    {0x27, 0xf7},
    {0x28, 0x7F},
    {0x29, 0x20},
    {0x33, 0x20},
    {0x34, 0x20},
    {0x35, 0x20},
    {0x36, 0x20},
    {0x32, 0x08},

    {0x47, 0x00},
    {0x48, 0x00},

    {0xfe, 0x01},
    {0x79, 0x00},
    {0x7d, 0x00},
    {0x50, 0x88},
    {0x5b, 0x0c},
    {0x76, 0x8f},
    {0x80, 0x70},
    {0x81, 0x70},
    {0x82, 0xb0},
    {0x70, 0xff},
    {0x71, 0x00},
    {0x72, 0x28},
    {0x73, 0x0b},
    {0x74, 0x0b},

    {0xfe, 0x00},
    {0x70, 0x45},
    {0x4f, 0x01},
    {0xf1, 0x07},

    {0xf2, 0x01},
};

#endif

static int gc0328_read_reg(sensor_t *sensor, uint8_t reg_addr)
{
    uint8_t reg_data;
    if (cambus_readb(sensor->slv_addr, reg_addr, &reg_data) != 0) {
        return -1;
    }
    return reg_data;
}

static int gc0328_write_reg(sensor_t *sensor, uint8_t reg_addr, uint16_t reg_data)
{
    return cambus_writeb(sensor->slv_addr, reg_addr, (uint8_t)reg_data);
}


static int gc0328_set_pixformat(sensor_t *sensor, pixformat_t pixformat)
{
    return 0;
}

static int gc0328_set_framesize(sensor_t *sensor, framesize_t framesize)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_framerate(sensor_t *sensor, framerate_t framerate)
{
    return 0;
}

static int gc0328_set_contrast(sensor_t *sensor, int level)
{
    int ret = 0;

    return ret;
}

static int gc0328_set_brightness(sensor_t *sensor, int level)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_saturation(sensor_t *sensor, int level)
{
    int ret = 0;

    return ret;
}

static int gc0328_set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling)
{
    int ret = 0;

    return ret;
}

static int gc0328_set_quality(sensor_t *sensor, int qs)
{
    int ret = 0;

    return ret;
}

static int gc0328_set_colorbar(sensor_t *sensor, int enable)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling)
{
   int ret = 0;
   return ret;
}

static int gc0328_get_gain_db(sensor_t *sensor, float *gain_db)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_auto_exposure(sensor_t *sensor, int enable, int exposure_us)
{
    int ret = 0;
    return ret;
}

static int gc0328_get_exposure_us(sensor_t *sensor, int *exposure_us)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
{
    int ret = 0;
    return ret;
}

static int gc0328_get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_hmirror(sensor_t *sensor, int enable)
{
    int ret = 0;
    return ret;
}

static int gc0328_set_vflip(sensor_t *sensor, int enable)
{
    int ret = 0;

    return ret;
}


int gc0328_reset(sensor_t* sensor)
{
    uint16_t index = 0;

    for (index = 0; sensor_default_regs[index][0]; index++)
    {
        // mp_printf(&mp_plat_print, "0x12,0x%02x,0x%02x,\r\n", sensor_default_regs[index][0], sensor_default_regs[index][1]);//debug
        dvp_sccb_send_data(GC0328_ADDR, sensor_default_regs[index][0], sensor_default_regs[index][1]);
        // mp_hal_delay_ms(1);
    }
    dvp_sccb_send_data(GC0328_ADDR,0xfe, 0x01);
    return 0;
}

int gc0328_init(sensor_t *sensor)
{
    //Initialize sensor structure.
    sensor->gs_bpp              = 2;
    sensor->reset               = gc0328_reset;
    sensor->read_reg            = gc0328_read_reg;
    sensor->write_reg           = gc0328_write_reg;
    sensor->set_pixformat       = gc0328_set_pixformat;
    sensor->set_framesize       = gc0328_set_framesize;
    sensor->set_framerate       = gc0328_set_framerate;
    sensor->set_contrast        = gc0328_set_contrast;
    sensor->set_brightness      = gc0328_set_brightness;
    sensor->set_saturation      = gc0328_set_saturation;
    sensor->set_gainceiling     = gc0328_set_gainceiling;
    sensor->set_quality         = gc0328_set_quality;
    sensor->set_colorbar        = gc0328_set_colorbar;
    sensor->set_auto_gain       = gc0328_set_auto_gain;
    sensor->get_gain_db         = gc0328_get_gain_db;
    sensor->set_auto_exposure   = gc0328_set_auto_exposure;
    sensor->get_exposure_us     = gc0328_get_exposure_us;
    sensor->set_auto_whitebal   = gc0328_set_auto_whitebal;
    sensor->get_rgb_gain_db     = gc0328_get_rgb_gain_db;
    sensor->set_hmirror         = gc0328_set_hmirror;
    sensor->set_vflip           = gc0328_set_vflip;

    // Set sensor flags
    SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0);
    SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_HSYNC, 0);
    SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_PIXCK, 1);
    SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_FSYNC, 0);
    SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_JPEGE, 1);

    return 0;
}